home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / misc / amag / sh9302a.lha / Patchen (S.53) / VPatch / VPatch.c < prev    next >
C/C++ Source or Header  |  1993-01-23  |  7KB  |  272 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <dos.h>
  5. #include <exec/exec.h>
  6. #include <intuition/intuition.h>
  7. #include <proto/dos.h>
  8. #include <proto/exec.h>
  9.  
  10. extern BPTR __asm newopen(register __d1 char *,register __d2 long);
  11. extern BPTR __asm newlock(register __d1 char *,register __d2 long);
  12. void main(int,char **);
  13.  
  14. extern struct DosLibrary *DOSBase;
  15. extern struct ExecBase   *SysBase;
  16. APTR oldOpen,oldLock;
  17.  
  18. /* Struktur, um Verwaltungsdaten für Extensionen aufzunehmen */
  19.  
  20. typedef struct
  21. {
  22.    char extension[80];
  23.    long length;
  24. } VINFO;
  25.  
  26. VINFO *info;
  27. long anzahl;
  28.  
  29. void main(int argc,char **argv)
  30. {
  31.    struct IntuiMessage send,*receive;
  32.    struct MsgPort      *port;
  33.    BPTR file;
  34.    char buffer[80];
  35.    int i=0;
  36.    VINFO *inf;
  37.  
  38.    /* Ist ein Message-Port mit Namen "VPort" vorhanden ? Ja, dann Message
  39.       mit der Klasse 0xffffffff absenden
  40.    */
  41.    
  42.    if (port=FindPort("VPort"))
  43.    {
  44.       send.Class=0xffffffff;
  45.       PutMsg(port,(struct Message*)&send);
  46.       FPuts(Output(),"DOS-Open() u. DOS-Lock() Patch aufgehoben\n");
  47.       return;
  48.    }
  49.    else
  50.    {
  51.       if (argc!=2)
  52.       {
  53.          FPuts(Output(),"FORMAT : vpatch <Parameterdatei>\n");
  54.          return;
  55.       }
  56.       
  57.       /* angegebene Parameterdatei einlesen */
  58.       
  59.       if (file=Open(argv[1],MODE_OLDFILE))
  60.       {
  61.          while (FGets(file,buffer,79))
  62.          {
  63.             
  64.             /* Keine Leerzeile */
  65.             
  66.             if (strcmp(buffer,"\n"))
  67.             {
  68.                /* "realloc()" von Hand ... */
  69.                
  70.                inf=info;
  71.                if (info=AllocVec((i+1)*sizeof(VINFO),MEMF_CLEAR|MEMF_PUBLIC))
  72.                {
  73.                   CopyMem(inf,info,i*sizeof(VINFO));
  74.                   FreeVec(inf);
  75.                   
  76.                   /* ... und dann Daten einkopieren */
  77.                   
  78.                   strcpy((*(info+i)).extension,buffer);
  79.                   (*(info+i)).length=strlen(buffer)-1;
  80.                   (*(info+i)).extension[(*(info+i)).length]='\0';
  81.                   i++;
  82.                }
  83.                else
  84.                {
  85.                   FreeVec(info);
  86.                   FPuts(Output(),"Kein freier Speicher für Extensionsliste\n");
  87.                   Close(file);
  88.                   return;
  89.                }
  90.             }
  91.          }
  92.          anzahl=i;
  93.          
  94.          /* Message-Port einrichten, Vektoren verbiegen und auf spezielle
  95.             Message warten, dann Vektoren wiederherstellen und Programm
  96.             beenden.
  97.          */
  98.          
  99.          if (port=CreateMsgPort())
  100.          {
  101.             port->mp_Node.ln_Name="VPort";
  102.             AddPort(port);
  103.             oldOpen=SetFunction((struct Library*)DOSBase,-30,newopen);
  104.             oldLock=SetFunction((struct Library*)DOSBase,-84,newlock);
  105.             FPuts(Output(),"DOS-Open() u. DOS-Lock() gepatcht\n");
  106.             Close(file);
  107.             do
  108.             {
  109.                receive=(struct IntuiMessage*)WaitPort(port);
  110.             } while (receive->Class!=0xffffffff);
  111.             FreeVec(info);
  112.             RemPort(port);
  113.             DeleteMsgPort(port);
  114.             SetFunction((struct Library*)DOSBase,-30,oldOpen);
  115.             SetFunction((struct Library*)DOSBase,-84,oldLock);
  116.          }
  117.       }
  118.       else if (!file)
  119.          FPuts(Output(),"Parameterdatei nicht vorhanden\n");
  120.    }  
  121.    return;
  122. }
  123.  
  124. extern BPTR __asm newopen(register __d1 char *name,register __d2 long mode)
  125. {
  126.    char newname[256],hilfe[256],*p;
  127.    BPTR fh;
  128.    short x=0,len,kenn=-1,pos=0,in=0;
  129.    
  130.    /* Zugriff auf globale Daten, Libraryadressen etc. */
  131.    
  132.    geta4();
  133.    strcpy(newname,name);
  134.    strcpy(hilfe,name);
  135.    strcat(hilfe,".vers");
  136.    len=strlen(name);
  137.    
  138.    /* Jetzt Open() wieder auf DOS-Library umstellen */
  139.    
  140.    SetFunction((struct Library*)DOSBase,-30,oldOpen);
  141.    
  142.    /* um welche Extension handelt es sich ? */
  143.    
  144.    for (x=0;x<anzahl && kenn==-1;x++)
  145.    {
  146.       if (!strnicmp(newname+(len-(*(info+x)).length),(*(info+x)).extension,
  147.                     (*(info+x)).length))
  148.       {
  149.          pos=len-(*(info+x)).length;
  150.          kenn=x;
  151.       }
  152.    }
  153.    
  154.    /* Neue Datei => Wenn keine Version angegeben, höchste lesen */
  155.    
  156.    if (mode==MODE_NEWFILE && kenn!=-1)
  157.    {
  158.       if (p=stpchr(newname,'.'))
  159.       {
  160.          /* Versionsnummer vorhanden ? */
  161.          
  162.          if (!(x=atoi(p+1)))
  163.          {
  164.             if (fh=Open(hilfe,MODE_OLDFILE))
  165.             {
  166.                FRead(fh,&x,sizeof(x),1);
  167.                Seek(fh,0,OFFSET_BEGINNING);
  168.             }
  169.             else
  170.             {
  171.                if (!(fh=Open(hilfe,MODE_NEWFILE)))
  172.                   x=1000;
  173.             }
  174.             
  175.             /* wenn Vers.-Nummer <1000 => Zusatzdatei 'updaten' */
  176.             if (x<999)
  177.             {
  178.                in=1;
  179.                x++;
  180.                FWrite(fh,&x,sizeof(x),1);
  181.                Close(fh);
  182.             }
  183.             else
  184.                return((BPTR)0);
  185.          }
  186.       }
  187.    }
  188.    
  189.    /* wie bei MODE_NEWFILE, nur kein update auf Zusatzdatei */
  190.    
  191.    else if (mode==MODE_OLDFILE && kenn!=-1)
  192.    {
  193.       if (p=stpchr(newname,'.'))
  194.       {
  195.          if (!(x=atoi(p+1)))
  196.          {
  197.             if (fh=Open(hilfe,MODE_OLDFILE))
  198.             {
  199.                in=1;
  200.                FRead(fh,&x,sizeof(x),1);
  201.                Close(fh);
  202.              }
  203.          }
  204.       }
  205.    }
  206.    
  207.    /* Neue Dateinamen mit Versionsnamen erstellen */
  208.    if (x && kenn!=-1 && in)
  209.    {
  210.       sprintf(newname+pos,".%03d",x);
  211.       strcpy(newname+pos+4,(*(info+kenn)).extension);
  212.    }
  213.    fh=Open(newname,mode);
  214.    
  215.    /* Datei öffnen, Vektor auf 'newopen' verbiegen, BPTR zurückgeben */
  216.    
  217.    SetFunction((struct Library*)DOSBase,-30,newopen);
  218.    return(fh);
  219. }
  220.  
  221. extern BPTR __asm newlock(register __d1 char *name,register __d2 long mode)
  222. {
  223.    BPTR lock,fh;
  224.    char newname[256],hilfe[256],vname[256],*p;
  225.    short version;
  226.    
  227.    /* Zugriff auf globale Daten, Libraryadressen etc. */
  228.    
  229.    geta4();
  230.    strcpy(newname,name);
  231.    strcpy(vname,name);
  232.    
  233.    /* Wenn keine Version angegeben, höchste lesen */
  234.    
  235.    if (p=stpchr(newname,'.'))
  236.    {
  237.       /* Versionsnummer vorhanden ? */
  238.       
  239.       if (!(version=atoi(p+1)))
  240.       {
  241.          strcpy(hilfe,p);
  242.          strcat(vname,".vers");
  243.       
  244.          /* originale Open()-Funktion, dann Versuch Zusatzdatei mit
  245.             Versionsnummer zu lesen
  246.          */
  247.       
  248.          SetFunction((struct Library*)DOSBase,-30,oldOpen);
  249.          if (fh=Open(vname,MODE_OLDFILE))
  250.          {
  251.             FRead(fh,&version,sizeof(version),1);
  252.             Close(fh);
  253.             
  254.             /* Versionsnummer in Dateiname einfügen */
  255.             
  256.             sprintf(p,".%03d",version);
  257.             strcat(newname,hilfe);
  258.          }
  259.          SetFunction((struct Library*)DOSBase,-30,newopen);
  260.       }
  261.    }
  262.    
  263.    /* Lock()-Funktion ausführen den Lock ermitteln, den Vektor wieder
  264.       verbiegen und den Lock zurückgeben
  265.    */
  266.    
  267.    SetFunction((struct Library*)DOSBase,-84,oldLock);
  268.    lock=Lock(newname,mode);
  269.    SetFunction((struct Library*)DOSBase,-84,newlock);
  270.    return(lock);
  271. }
  272.